// 1.引入框架
// node项目采用 common.js，不能采用 import 引入，只能用 require 方式
const express = require("express");
let request = require("request"); // 用于请求瓦片地图
let bagpipe = require("bagpipe"); //  用于异步请求数量控制
// 引入fs文件读写模块
const fs = require("fs");
const os = require("os");
const cors = require("cors");

let bag = new bagpipe(100, { timeout: 2000 }); //限制请求数，此处为100，可根据网络情况修改
let mapPath = "./tiles"; // 瓦片目录


// 服务端口
const port = 8888;
// 2.创建应用
const app = express();
app.use(express.urlencoded());
// 3.创建路由规则
// get请求
// 下载范围内离线地图瓦片接口
app.post("/api/downloadMap", (req, response) => {
  downloadMap(req, response);
});
//放开所有跨域
app.use(cors());
// 4.监听端口启动服务
app.listen(port, () => {
  console.log("server is running at: http://localhost:" + port);
  console.log("server start on: http://" + getIPv4() + ":" + port);
});

// 下载范围内离线地图瓦片
function downloadMap(req, response) {
  try {
    // 设置响应头 设置允许跨域
    response.setHeader("Access-Control-Allow-Origin", "*");
    // 设置所有相应头可用
    response.setHeader("Access-Control-Allow-Headers", "*");
    // console.log("req",req);
    let query = req.body;
    // console.log("query",query);
    const tileALL = query.tileALL;
    const minzoom = Number(query.minzoom);
    const maxzoom = Number(query.maxzoom);
    // console.log("query",tileALL);
    fs.access(mapPath, fs.constants.F_OK, (err) => {
      // 创建tiles文件夹
      if (err) fs.mkdir(mapPath, (err) => {});
      for (let z = minzoom; z <= maxzoom; z++) {
        // for (let z = minzoom; z <= tileALL.length - 1; z++) {
        fs.access(`${mapPath}/${z}`, fs.constants.F_OK, (err) => {
          // 创建tiles/Z文件夹 ,Z是层级
          if (err) fs.mkdir(`${mapPath}/${z}`, (err) => {});
          for (let x = tileALL[z].x[0]; x <= tileALL[z].x[1]; x++) {
            fs.access(`${mapPath}/${z}/${x}`, fs.constants.F_OK, (err) => {
              // 创建tiles/Z/X文件夹 ,X是瓦片横坐标
              if (err) fs.mkdir(`${mapPath}/${z}/${x}`, (err) => {});
            });
          }
        });
      }
      // 文件夹可能较多，等待2s开始下载
      setTimeout(() => {
        task(tileALL, minzoom, maxzoom);
      }, 2000);
    });
  } catch (e) {
    let result = {
      msg: "",
      code: 200,
    };
    response.status(500);
    result.code = 500;
    result.msg = e;
    response.json(result);
    throw e;
  }
}

function task(tileALL, minzoom, maxzoom) {
  // console.log("tileALL:",tileALL);
  for (let z = minzoom; z <= maxzoom; z++) {
    // for (let z = 3; z <= tileALL.length - 1; z++) {
    for (let x = tileALL[z].x[0]; x <= tileALL[z].x[1]; x++) {
      for (let y = tileALL[z].y[0]; y <= tileALL[z].y[1]; y++) {
        // 将下载任务推入队列，bag会以100张为单位批量下载
        // console.log("download:",x,y,z);
        bag.push(download, x, y, z);
      }
    }
  }
}
function download(i, j, z) {
  const url = `http://webst01.is.autonavi.com/appmaptile?style=6&x=${i}&y=${j}&z=${z}`;
  console.log("url:", url);
  request({ url, timeout: 6000 }, (err, res, body) => {
    if (err) {
      console.log(err);
    }
  }).pipe(fs.createWriteStream(`${mapPath}/${z}/${i}/${j}.png`));
}

// 获取ip地址
function getIPv4() {
  const interfaces = os.networkInterfaces(); //获取网络接口列表
  let ipv4s = []; //同一接口可能有不止一个IP4v地址，所以用数组存

  Object.keys(interfaces).forEach(function (key) {
    interfaces[key].forEach(function (item) {
      //跳过IPv6 和 '127.0.0.1'
      if ("IPv4" !== item.family || item.internal !== false) return;

      ipv4s.push(item.address); //可用的ipv4s加入数组
      console.log(key + "--" + item.address);
    });
  });
  return ipv4s[0]; //返回一个可用的即可
}
